import {forwardRef, Inject, Injectable, Optional} from '@angular/core';
import {Title, DOCUMENT} from '@angular/platform-browser';
import {Router, ActivationEnd} from '@angular/router';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import {SEO_CONFIG} from "@core/seo/seo.module";
import {SeoConfig} from "@core/seo/seo-config.modal";

// const isDefined = (val: any) => typeof val !== 'undefined';

@Injectable()
export class SeoService {
  constructor(
    private _router: Router,
    @Inject(DOCUMENT) private document: any,
    @Inject(forwardRef(() => SEO_CONFIG)) private seoConfig: SeoConfig,
    private titleService: Title,
  ) {

    this._router.events
      .filter(event => (event instanceof ActivationEnd))
      .subscribe((activationEnd: ActivationEnd) => {
        if (activationEnd.snapshot.data.meta) {
          this._updateMetaTags(activationEnd.snapshot.data.meta);
        }
      });
  }


  private _getMetaTag(name: string): HTMLElement {
    let el: HTMLElement = this.document.querySelector(`meta[name='${name}']`);
    if (!el) {
      el = this.document.createElement('meta');
      el.setAttribute('name', name);
      this.document.head.appendChild(el);
    }
    return el;
  }

  private _updateMetaTags(meta: any = {}) {

    if (meta.disableUpdate) {
      return false;
    }

    this.setTitle(meta.title, meta.titleSuffix);

    Object.keys(meta).forEach(key => {
      if (key === 'title' || key === 'titleSuffix') {
        return;
      }
      this.setTag(key, meta[key]);
    });
  }

  public setTitle(title: string, titleSuffix?: string): SeoService {
    const titleElement = this._getMetaTag('title');
    const ogTitleElement = this._getMetaTag('og:title');
    /*let titleStr = (title != null) ? title : (this.seoConfig.defaults['title'] || '');
    if (this.seoConfig.useTitleSuffix) {
      titleStr += (titleSuffix != null) ? titleSuffix : (this.seoConfig.defaults['titleSuffix'] || '');
    }*/
    const config = this.seoConfig;
    title = title || config.defaults.title || '';
    if (config.useTitleSuffix) {
      title += titleSuffix || config.defaults.titleSuffix || '';
    }
    titleElement.setAttribute('content', title);
    ogTitleElement.setAttribute('content', title);
    this.titleService.setTitle(title);
    return this;
  }

  public setTag(tag: string, value: string): SeoService {
    if (tag === 'title' || tag === 'titleSuffix') {
      throw new Error(`Attempt to set ${tag} through 'setTag': 'title' and 'titleSuffix' are reserved tag names.
      Please use 'SeoService.setTitle' instead`);
    }
    const tagElement = this._getMetaTag(tag);
    const tagStr = (value != null) ? value : (this.seoConfig.defaults[tag] || '');
    tagElement.setAttribute('content', tagStr);
    /* if (tag === 'description') {
       const ogDescElement = this._getMetaTag('og:description');
       ogDescElement.setAttribute('content', tagStr);
     }*/
    return this;
  }

  public setTKD(title: string, keywords: string, description: string) {
    this.setTitle(title)
      .setTag('keywords', keywords)
      .setTag('description', description);
  }

}
